package pl.enigmatic.parser.xml;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Map;
import java.util.Map.Entry;

import pl.enigmatic.util.Reflection;
import pl.enigmatic.parser.XMLAlias;


@SuppressWarnings("rawtypes")
public class FinalPropertyParser extends BasicFinalPropertyParser<FinalPropertyParser.Getter> implements ObjectCreator {

	protected static class Getter extends pl.enigmatic.parser.xml.BasicFinalPropertyParser.Getter {

		private final Method method;

		Getter(final String name, final Method m) {
			super(name, m.getReturnType());
			method = m;
		}

		public Object get(final String property, final Object target) {
			try {
				return method.invoke(target);
			} catch (final Exception e) {}
			return null;
		}
	}

	FinalPropertyParser(final Parser<?> owner) {
		super(owner);
		final Class<?> clazz = owner.getClazz();
		final Map<String, Method> map = Reflection.getDeclaredGetters(clazz);
		for (final Entry<String, Method> m : map.entrySet()) {
			Field f = null;
			try {
				f = clazz.getDeclaredField(m.getKey());
			} catch (final Exception e) {
				continue;
			}
			final int mod = f.getModifiers();
			if (Modifier.isFinal(mod) && !Modifier.isStatic(mod)) {
				final String property = m.getKey();
				final Method mtd = m.getValue();
				accessors.put(property, new Getter(property, mtd));
				if (mtd.isAnnotationPresent(XMLAlias.class)) {
					accessors.addAliases(property, mtd.getAnnotation(XMLAlias.class).value());
				}
				if (f.isAnnotationPresent(XMLAlias.class)) {
					accessors.addAliases(property, f.getAnnotation(XMLAlias.class).value());
				}
			}
		}
	}
}
